<?php
/*
 * Copyright 2009 Surf Chen <http://www.surfchen.org>
 *
 *
 * This source code is under the terms of the
 * GNU Lesser General Public License. 
 * see <http://www.gnu.org/licenses/lgpl.txt>
 */

/*
    ed2k hash algorithm:
    Divided into blocks, 
    Last block: >=0 and <9500KB.
    Other blocks: == 9500KB,
    (If filesize is exact multi times of BLOCK_SIZE, the last block is 0)

    if the number of blocks is 1,the file hash will be that single block hash.
    else the file hash will be the hash of all blocks's hash.
*/

define('ED2K_BLOCK_SIZE',9728000);

/**
 * Generate the ed2k hash string of file.
 *
 * @param    string  the path of file to be hashed
 * @param    bool    output hex format or binary format. default = hex
 * @return   string  hash of $file
 */
function ed2k_hash($file,$hex_output=true) {
    $file_size=filesize($file);
    $block_num=floor($file_size/ED2K_BLOCK_SIZE)+1;

    $fp=fopen($file,'rb');
    if ($block_num==1) {
        $context=hash_init('md4');
        hash_update_stream($context,$fp,ED2K_BLOCK_SIZE);
        $ed2k_hash=hash_final($context,!$hex_output);
    } else {
        $hash='';
        for ($i=0;$i<$block_num;$i++) {
            $context=hash_init('md4');
            hash_update_stream($context,$fp,ED2K_BLOCK_SIZE);
            $hash.=hash_final($context,true);
        }
        $context=hash_init('md4');
        hash_update($context,$hash);
        $ed2k_hash=hash_final($context,!$hex_output);
    }
    fclose($fp);
    return $ed2k_hash;
}
